package com.zkthink.ceres.pay.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zkthink.base.R;
import com.zkthink.base.service.SuperServiceImpl;
import com.zkthink.ceres.pay.dao.WxPayAuthMapper;
import com.zkthink.ceres.pay.dto.WxAuthAccountDTO;
import com.zkthink.ceres.pay.dto.WxAuthQrCodeDTO;
import com.zkthink.ceres.pay.dto.WxAuthStatusDTO;
import com.zkthink.ceres.pay.dto.WxPayAuthSaveDTO;
import com.zkthink.ceres.pay.entity.WxPayAuth;
import com.zkthink.ceres.pay.enums.WxAuthAuditStateEnum;
import com.zkthink.ceres.pay.service.WxPayAuthService;

import com.zkthink.ceres.pay.wechat.v3.entity.request.applyments.*;
import com.zkthink.ceres.pay.wechat.v3.entity.result.applyments.ApplymentsStateEnum;
import com.zkthink.ceres.pay.wechat.v3.entity.result.applyments.QueryApplymentsResult;
import com.zkthink.ceres.pay.wechat.v3.service.ecommerce.ApplymentsService;
import com.zkthink.ceres.tenant.entity.TenantApply;
import com.zkthink.context.BaseContextHandler;
import com.zkthink.database.mybatis.conditions.Wraps;
import com.zkthink.dozer.DozerUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * <p>
 * 业务实现类
 * 微信支付认证
 * </p>
 *
 * @author vivi.huang
 * @date 2020-06-28
 */
@Slf4j
@Service
@AllArgsConstructor
public class WxPayAuthServiceImpl extends SuperServiceImpl<WxPayAuthMapper, WxPayAuth> implements WxPayAuthService {

    private WxPayAuthMapper wxPayAuthMapper;
    private DozerUtils dozerUtils;
    private ApplymentsService applymentsService;

    @Override
    public R<WxPayAuth> getWxPayAuthDetail() {

        //查询支付认证详情
        WxPayAuth wxPayAuth = this.getOne(Wraps.lbQ());

        //如果为空，就是第一次申请店铺认证
        //使用商家入驻的信息作为店铺认证初始化的值
        if (wxPayAuth == null) {
            return R.success(initFromTenantApplyDetail());
        }

        return R.success(wxPayAuth);
    }

    private WxPayAuth initFromTenantApplyDetail() {
        TenantApply tenantApply = wxPayAuthMapper.getTenantApply(BaseContextHandler.getTenant());
        return Optional.ofNullable(tenantApply).map(t -> dozerUtils.map(tenantApply, WxPayAuth.class)).orElse(null);
    }

    @Override
    public R<WxAuthQrCodeDTO> getWxPayAuthQrCode() {
        //调用微信接口查询商户进件状态
        WxAuthQrCodeDTO wxAuthQrCodeDTO = getApplymentsData();
        return R.success(wxAuthQrCodeDTO);
    }

    private WxAuthQrCodeDTO getApplymentsData() {
        QueryApplymentsResult queryApplymentsResult = getQueryApplymentsResult();
        log.info("调用微信进件-查询申请状态API成功");
        WxAuthQrCodeDTO wxAuthQrCodeDTO =  new WxAuthQrCodeDTO();
        //mock
        queryApplymentsResult.setSignUrl("https://pay.weixin.qq.com/public/apply4ec_sign/s?applymentId=2000002126198476&sign=b207b673049a32c858f3aabd7d27c7ec");

        //当请求签约 mock
        queryApplymentsResult.setApplymentState(ApplymentsStateEnum.FINISH.name());
        updateApplymentsStatus(queryApplymentsResult);

        wxAuthQrCodeDTO.setQrCodeData(queryApplymentsResult.getSignUrl());
        return wxAuthQrCodeDTO;
    }

    private QueryApplymentsResult getQueryApplymentsResult() {
        QueryApplymentsResult queryApplymentsResult =  new QueryApplymentsResult();
        queryApplymentsResult.setAccountValidation(new AccountValidation());
        return queryApplymentsResult;
//        return applymentsService.queryApplymentStatus(buildQueryApplymentsRequest());
    }

    @Override
    public R<WxAuthStatusDTO> getWxPayAuthStatus() {
        WxPayAuth wxPayAuth = this.getOne(Wraps.lbQ());
        WxAuthStatusDTO wxAuthStatusDTO = new WxAuthStatusDTO();
        wxAuthStatusDTO.setAuditState(wxPayAuth.getAuditState());
        return R.success(wxAuthStatusDTO);
    }

    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    @Override
    public R<WxPayAuth> submitPayAuth(WxPayAuthSaveDTO wxPayAuthSaveDTO) {

        WxPayAuth wxPayAuth = this.getOne(Wraps.lbQ());

        if (wxPayAuth == null) {
            //保存认证申请信息到数据库
            wxPayAuth = insertPayAuthDetail(wxPayAuthSaveDTO);
            log.info("保存认证申请详情成功");
        } else {
            //更新认证申请详情
            wxPayAuth = updatePayAuthDetail(wxPayAuthSaveDTO);
            log.info("更新认证申请详情成功");
        }

        //同步数据到微信服务
        syncDataToWxPayService(wxPayAuthSaveDTO);

        return R.success(wxPayAuth);
    }

    private WxPayAuth updatePayAuthDetail(WxPayAuthSaveDTO wxPayAuthSaveDTO) {
        WxPayAuth wxPayAuth = dozerUtils.map(wxPayAuthSaveDTO, WxPayAuth.class);
        //默认审核中
        wxPayAuth.setAuditState(WxAuthAuditStateEnum.AUDITING.getCode());
        //先删除原来的数据
        this.remove(Wraps.lbQ());
        //保存
        this.save(wxPayAuth);
        return wxPayAuth;
    }

    @Override
    public R<WxAuthAccountDTO> getWxAuthAccountDetail() {
        //调用微信查询进件状态接口
        QueryApplymentsResult queryApplymentsResult = getQueryApplymentsResult();
        AccountValidation accountValidation = queryApplymentsResult.getAccountValidation();
        //mock数据
        mockAccountValidation(accountValidation);
        WxAuthAccountDTO wxAuthAccountDTO = dozerUtils.map(accountValidation, WxAuthAccountDTO.class);
        wxAuthAccountDTO.setAccountNumber(accountValidation.getAccountNo());
        wxAuthAccountDTO.setBankName(accountValidation.getDestinationAccountBank());
        return R.success(wxAuthAccountDTO);
    }

    private void mockAccountValidation(AccountValidation accountValidation) {
        accountValidation.setAccountName("深圳市CCCC科技有限公司");
        accountValidation.setAccountNo("56565656626165461");
        accountValidation.setDestinationAccountBank("招商银行深圳分行高新园支行");
        accountValidation.setDestinationAccountName("深圳市腾讯计算机系统有限公司");
        accountValidation.setDestinationAccountNumber("700009987777788888888");
        accountValidation.setPayAmount("100");
        accountValidation.setDeadline("2020-07-15 12:00:00");
        accountValidation.setCity("深圳");
        accountValidation.setRemark("公众号注册");
    }

    private QueryApplymentsRequest buildQueryApplymentsRequest() {
        QueryApplymentsRequest queryApplymentsRequest = new QueryApplymentsRequest();
        queryApplymentsRequest.setOutRequestNo(BaseContextHandler.getTenant());
        return queryApplymentsRequest;
    }

    @Override
    public R<WxAuthAccountDTO> getWxAuthAccountStatus() {
        //调用微信查询进件状态接口
        QueryApplymentsResult queryApplymentsResult = getQueryApplymentsResult();
        WxAuthAccountDTO wxAuthAccountDTO = new WxAuthAccountDTO();
        wxAuthAccountDTO.setSuccess(getSuccessState(queryApplymentsResult.getApplymentState()));
        return R.success(wxAuthAccountDTO);
    }

    private Boolean getSuccessState(String applymentState) {
        return true;
    }

    @Override
    public Boolean checkApplyStatus() {

        //调用微信查询进件状态接口
        QueryApplymentsResult queryApplymentsResult = getQueryApplymentsResult();
        //更新状态
        updateStatusToWxPayAuth(queryApplymentsResult);

        return true;
    }

    private void updateStatusToWxPayAuth(QueryApplymentsResult queryApplymentsResult) {

        //更新账户认证信息
        if (queryApplymentsResult.getAccountValidation() != null) {
            AccountValidation accountValidation = queryApplymentsResult.getAccountValidation();
            AuditDetail auditDetail = queryApplymentsResult.getAuditDetail();
            updateAccountDetail(accountValidation.getDestinationAccountName(),
                                accountValidation.getDestinationAccountNumber(),
                                accountValidation.getPayAmount(),
                                accountValidation.getDeadline(),
                                accountValidation.getRemark(),
                                auditDetail.getRejectReason(),
                                queryApplymentsResult.getSubMchid());
        }

        //更新审核状态
        updateApplymentsStatus(queryApplymentsResult);

    }

    private void updateAccountDetail(String destinationAccountName, String destinationAccountNumber, String payAmount, String deadline, String remark, String rejectReason, String subMchid) {
        this.wxPayAuthMapper.updateAccountDetail(destinationAccountName,
                                                destinationAccountNumber,
                                                payAmount,
                                                deadline,
                                                remark,
                                                rejectReason,
                                                subMchid);
    }


    private void updateApplymentsStatus(QueryApplymentsResult queryApplymentsResult) {
        ApplymentsStateEnum applymentsStateEnum = ApplymentsStateEnum.valueOf(queryApplymentsResult.getApplymentState().toUpperCase());
        WxAuthAuditStateEnum wxAuthAuditStateEnum;
        switch (applymentsStateEnum) {
            case CHECKING:
            case AUDITING:
            case ACCOUNT_NEED_VERIFY:
            case FROZEN:
                wxAuthAuditStateEnum = WxAuthAuditStateEnum.AUDITING;
                break;
            case REJECTED:
                wxAuthAuditStateEnum = WxAuthAuditStateEnum.AUDIT_FAIL;
                break;
            case NEED_SIGN:
                wxAuthAuditStateEnum = WxAuthAuditStateEnum.AUDIT_PASS;
                break;
            case FINISH:
                wxAuthAuditStateEnum = WxAuthAuditStateEnum.USING;
                break;
            default:
                wxAuthAuditStateEnum = WxAuthAuditStateEnum.AUDITING;
        }

        this.wxPayAuthMapper.updateState(wxAuthAuditStateEnum.getCode());
        log.info("微信认证申请状态为:[{}]，更新数据库成功", wxAuthAuditStateEnum.getDesc());
    }

    private void syncDataToWxPayService(WxPayAuthSaveDTO wxPayAuthSaveDTO) {
        //code wx.submitAuth
//        CreateApplymentsResult createApplymentsResult = applymentsService.createApplyments(buildCreateApplymentsRequest(wxPayAuthSaveDTO));
//        log.info("同步数据到微信支付-二级商户进件接口成功:[{}]", JSON.toJSONString(createApplymentsResult));
    }

    private CreateApplymentsRequest buildCreateApplymentsRequest(WxPayAuthSaveDTO wxPayAuthSaveDTO) {
        CreateApplymentsRequest createApplymentsRequest = new CreateApplymentsRequest();
        createApplymentsRequest.setBusinessLicenseInfo(dozerUtils.map(wxPayAuthSaveDTO, BusinessLicenseInfo.class));
        createApplymentsRequest.setOrganizationCertInfo(dozerUtils.map(wxPayAuthSaveDTO, OrganizationCertInfo.class));
        createApplymentsRequest.setIdCardInfo(dozerUtils.map(wxPayAuthSaveDTO, IdCardInfo.class));
        createApplymentsRequest.setIdDocInfo(dozerUtils.map(wxPayAuthSaveDTO, IdDocInfo.class));
        createApplymentsRequest.setAccountInfo(dozerUtils.map(wxPayAuthSaveDTO, AccountInfo.class));
        createApplymentsRequest.setContactInfo(dozerUtils.map(wxPayAuthSaveDTO, ContactInfo.class));
        createApplymentsRequest.setSalesSceneInfo(dozerUtils.map(wxPayAuthSaveDTO, SalesSceneInfo.class));
        log.info("构造微信认证申请请求参数成功");
        return createApplymentsRequest;
    }

    private WxPayAuth insertPayAuthDetail(WxPayAuthSaveDTO wxPayAuthSaveDTO) {
        WxPayAuth wxPayAuth = dozerUtils.map(wxPayAuthSaveDTO, WxPayAuth.class);
        //默认审核中
        wxPayAuth.setAuditState(WxAuthAuditStateEnum.AUDITING.getCode());
        this.save(wxPayAuth);
        return wxPayAuth;
    }
}
